<?php
namespace App\Http\Admin\Middleware;

use Closure;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Redis;
use Tymon\JWTAuth\Facades\JWTAuth;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Http\Middleware\BaseMiddleware;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;



class RefreshToken extends BaseMiddleware
{

    public function handle($request, Closure $next)
    {
        dump(11);
        // 检查此次请求中是否带有 token，如果没有则抛出异常。
        $this->checkForToken($request);
        dump(22);
        // 使用 try 包裹，以捕捉 token 过期所抛出的 TokenExpiredException  异常
        try {
           dump(33);
            // 检测用户的登录状态，如果正常则通过
            if ($this->auth->parseToken()->authenticate()) {
                return $next($request);
            }
            
            throw new UnauthorizedHttpException('jwt-auth', '未登录');

        } catch (TokenExpiredException $exception) {
            dump(44);
            // 此处捕获到了 token 过期所抛出的 TokenExpiredException 异常，我们在这里需要做的是刷新该用户的 token 并将它添加到响应头中
            try {
                // 刷新用户的 token
                // 判断oldtoken 和 request 的旧token是否相同
                $user  = $this->auth->user();
                $key = 'user'.$user['id'].'token';
                $res_token = explode(" ",$request->header('Authorization'))[1];
                $old_token = Redis::get($key);

                if($res_token == $old_token){
                    $token = JWTAuth::parseToken()->refresh();
                    Redis::command('set',[$key,$token]);
                    // 使用一次性登录以保证此次请求的成功
                    Auth::guard('jwtapis')->onceUsingId($this->auth->manager()->getPayloadFactory()->buildClaimsCollection()->toPlainArray()['sub']);
                }else{
                    throw new UnauthorizedHttpException('jwt-auth', "只有一台设备可以登录");
                }

            } catch (JWTException $exception) {
                // 如果捕获到此异常，即代表 refresh 也过期了，用户无法刷新令牌，需要重新登录。
                throw new UnauthorizedHttpException('jwt-auth', $exception->getMessage());
            }
        }

        return $this->setAuthenticationHeader($next($request),$token);
    }
}
